<?php
/**
 * EIcecatProduct.php
 * @author Artem Azarov <bel-azar@ya.ru>
 * Date: 9/10/12
 * Time: 2:58 PM
 *
 */
/**
 * Class load information for products from Open-icecat server
 * @package extensions.icecatConnect
 *
 */
class EIcecatProduct extends CComponent
{
    const OUTPUT_TYPE_PRODUCT = 'productxml';
    const OUTPUT_TYPE_META = 'metaxml';

    const CACHE_EXPIRE_TIME = 3600;

    const LOG_CATEGORY = 'application.icecat';


    public $dataUrl = 'http://data.icecat.biz/xml_s3/xml_server3.cgi?';
    public $login = 'openIcecat-xml';
    public $password = 'freeaccess';

    public $locale = 'EN';
    public $outputType = self::OUTPUT_TYPE_PRODUCT;


    /**
     * Initialization
     */
    public function init()
    {
        if ($this->outputType !== self::OUTPUT_TYPE_PRODUCT && $this->outputType !== self::OUTPUT_TYPE_META) {
            Yii::log('Wrong output type', CLogger::LEVEL_WARNING, self::LOG_CATEGORY);
        }
    }


    /**
     * Get product information by mpn-vendor
     * @param $mpn
     * @param $vendor
     * @return bool|CAttributeCollection
     */
    public function getProductByMpn($mpn, $vendor)
    {
        $downloadUrl = $this->_getProductUrl(
            array(
                "prod_id" => $mpn,
                "vendor" => $vendor,
                "lang" => $this->locale,
                "output" => $this->outputType
            )
        );

        $product = $this->_getDataFromIcecat($downloadUrl);

        return $product;
    }

    /**
     * Get product information by ean(upc,gtin)
     * @param $mpn
     * @param $vendor
     * @return bool|CAttributeCollection
     */
    public function getProductByEan($ean)
    {
        $downloadUrl = $this->_getProductUrl(
            array(
                "ean_upc" => $ean,
                "lang" => $this->locale,
                "output" => $this->outputType
            )
        );

        $product = $this->_getDataFromIcecat($downloadUrl);

        return $product;
    }

    /**
     * Get data from ICECat cgi script
     * @param $url
     * @return bool|CAttributeCollection
     */
    protected function _getDataFromIcecat($url)
    {
        $product = Yii::app()->cache->get($url);
        if (!$product) {
            try {
                $ch = curl_init();
                curl_setopt($ch, CURLOPT_URL, $url);
                curl_setopt($ch, CURLOPT_USERPWD, $this->login . ":" . $this->password);
                curl_setopt($ch, CURLOPT_HTTPHEADER,  array('Content-type: text/xml;charset=UTF-8'));
                curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
                curl_setopt($ch,CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1");
                $xml = curl_exec($ch);

                $responseCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

                curl_close($ch);


                if ($responseCode !== 200){
                    //throw new CException("Unsuccessful response, get code $responseCode");
                }

                if (!$xml){
                    throw new CException("Cannot connect to icecat on $url : " . curl_error($ch));
                }

                //transform xml into data
                if ($this->outputType === self::OUTPUT_TYPE_PRODUCT) {
                    $product = $this->_parseProductXml($xml);
                } elseif($this->outputType === self::OUTPUT_TYPE_META) {
                    //TODO implement meta parsing
                }

                if (empty($product)) {
                    throw new CException('Products content was not loaded');
                }

                Yii::app()->cache->set($url, $product, self::CACHE_EXPIRE_TIME);
                return $product;

            } catch (Exception $e) {
                Yii::log("Error loading icecat-info: " . $e->getMessage(), CLogger::LEVEL_WARNING, self::LOG_CATEGORY);
            }
            return false;
        } else {
            return $product;
        }
    }

    /**
     * Transform string xml data to array
     * @param $xml
     * @return CAttributeCollection
     */
    protected function _parseProductXml($xml)
    {
        try {
            libxml_use_internal_errors(true);
            $data = simplexml_load_string($xml);

            /*if (!$data){
                $data = simplexml_load_string(utf8_encode($xml));
            }*/

            if (!$data) {
                throw new CException('Get non-xml data: '. $xml);
            }

            if (!empty($data->Product['ErrorMessage'])) {
                throw new CException('Get error: ' . $data->Product['ErrorMessage']);
            }

            $product = new CAttributeCollection;

            $productTag = $data->Product;

            $product->mpn = (string)$productTag['Prod_id'];
            $product->vendor = (string)$productTag->Supplier['Name'];
            $product->shortDescription = (string)$productTag->ProductDescription['ShortDesc'];
            $product->longDescription = (string)$productTag->ProductDescription['LongDesc'];
            $product->lowPicUrl = (string)$productTag["LowPic"];
            $product->highPicUrl = (string)$productTag["HighPic"];
            $product->name = (string)$productTag["Name"];

            $eanCodes = array();
            foreach($productTag->EANCode as $ean){
                $eanCodes[] = (string)$ean['EAN'];
            }

            if (!empty($eanCodes)) {
                $product->eans = $eanCodes;
            }

            $product->gallery = $this->_parseGallery($productTag->ProductGallery->ProductPicture);
            $product->related = $this->_parseRelated($productTag->ProductRelated);
            $product->specifications = $this->_parseSpecifications($productTag->CategoryFeatureGroup, $productTag->ProductFeature);
            return $product;
        } catch(Exception $e) {
            Yii::log("Error while parse xml: " . $e->getMessage(), CLogger::LEVEL_WARNING, self::LOG_CATEGORY);
            return false;
        }
    }

    /**
     * Form gallery array
     * @param $galleryTags
     * @return array|null
     */
    protected  function _parseGallery($galleryTags)
    {
        if (!count($galleryTags)){
            return null;
        }
        $galleryPhotos = array();
        foreach($galleryTags as $photoTag){
            if($photoTag["Size"] > 0){
                $picHeight = (int)$photoTag["PicHeight"];
                $picWidth = (int)$photoTag["PicWidth"];
                $thumbUrl = (string)$photoTag["ThumbPic"];
                $picUrl = (string)$photoTag["Pic"];

                $galleryPhotos[] = array(
                    'height' => $picHeight,
                    'width' => $picWidth,
                    'thumb' => $thumbUrl,
                    'pic' => $picUrl
                );
            }
        }
        return $galleryPhotos;
    }

    /**
     * Form related products array
     * @param $relatedProductsArray
     * @return array|null
     */
    protected function _parseRelated($relatedProductsArray)
    {
        $relatedProducts = null;
        if(count($relatedProductsArray)){
            foreach($relatedProductsArray as $related){
                $productTag = $related->Product;

                $product = new CAttributeCollection();
                $product->name = (string)$productTag['Name'];
                $product->thumb = (string)$productTag['ThumbPic'];
                $product->mpn = (string)$productTag['Prod_id'];
                $productSupplier = $productTag->Supplier;
                $productSupplierId = (int)$productSupplier['ID'];
                $product->supplier_thumb = 'http://images2.icecat.biz/thumbs/SUP'.$productSupplierId.'.jpg';
                $product->supplier_name = (string)$productSupplier['Name'];

                $relatedProducts[] = $product;
            }
        }
        return $relatedProducts;
    }

    /**
     * Form product features
     * @param $specGroups
     * @param $specFeatures
     * @return array
     */
    protected function _parseSpecifications($specGroups, $specFeatures){
        $descriptionArray = array();

        foreach($specFeatures as $feature){
            $id = (int)$feature['CategoryFeatureGroup_ID'];
            $featureText = (string)$feature["Presentation_Value"];
            $featureName = (string)$feature->Feature->Name["Value"];
            foreach($specGroups as $group){
                $groupId = (int)$group["ID"];
                if ($groupId == $id){
                    $groupName = (string) $group->FeatureGroup->Name["Value"];
                    $rating = (int)$group['No'];
                    $descriptionArray[$rating][$groupName][$featureName] = $featureText;
                    break;
                }
            }
        }

        krsort($descriptionArray);
        return $descriptionArray;
    }

    /**
     * Form download url
     * @param $urlParams
     * @return string
     */
    protected function _getProductUrl($urlParams)
    {
        /*
        foreach ($urlParams as &$param) {
            $param = urlencode($param);
        }*/
        return $this->dataUrl . http_build_query($urlParams);
    }

}
